/**
 * 图论
 * 树形dp
 * */

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
int head[100100]; // head[i] 
int cnt; // edge number
int dp[1000][1000];
struct s{
    int u; // begin node
    int v; // end node
    int next; // last edge number express start from edegs that value is i
}edge[100010];
// build graph 
void add (int u, int v) {
    edge[cnt].u = u;
    edge[cnt].v = v;
    edge[cnt].next = head[u];
    head[u] = cnt++;
}
// dfs, pre express parent node
void dfs(int u, int pre) {
    for (int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].v;
        if (pre == v) continue; // parent node equals final node , don't need dp
        dfs(v, u);
        dp[u][1] += dp[v][0];
        dp[u][0] += max(dp[v][0], dp[v][1]);
    }
}
int main() {
    int n;
    cin >> n;
    memset(head, -1, sizeof(head));
    memset(dp, 0, sizeof(dp));
    for (int _ = 1; _ <= n; _++) cin >> dp[_][1];
    for (int _ = 1; _ < n; _++) {
        int a,b;
        cin >> a >> b;
        add(a,b);
        add(b,a);
    }
    dfs(1, -1); // from the first node start;
    cout << max(dp[1][1], dp[1][0]) << endl;
    return 0;
}